package hamsterpolice.todo.model;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import hamsterpolice.todo.data.DataAdapter;
import hamsterpolice.todo.data.DataNotFoundException;
import hamsterpolice.todo.data.Model;
import hamsterpolice.todo.data.UnhandledCriteriaException;

public class Category extends Model<Category> implements Parcelable {
	private static final String TAG = "Category";
	private String name = null;
	private User user = null;
	
	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeLong(getID());
		dest.writeString(name);
		dest.writeParcelable(user, flags);
	}

	public static final Parcelable.Creator<Category> CREATOR = new Parcelable.Creator<Category>() {
		public Category createFromParcel(Parcel in) {
			return new Category(in);
		}

		public Category[] newArray(int size) {
			return new Category[size];
		}
	};

	private Category(Parcel in) {
		setID(in.readLong());
		name = in.readString();
		user = in.readParcelable(null);
	}

	public Category(Context context){
		this(new CategoryDataAdapter(context));
	}
	
	public Category(DataAdapter<Category> dataAdapter){
		super(dataAdapter);
	}
	
	public static Category get(Context context, long id) throws DataNotFoundException{
		return get(new CategoryDataAdapter(context), id);
	}
	
	public static Category get(DataAdapter<Category> dataAdapter, long id) throws DataNotFoundException{
		
		Cursor c = null;
		try{
			try {
				c = dataAdapter.get(new IDCriterion(id));
			} catch (UnhandledCriteriaException e) {
				Log.e(TAG, "The Data Adapter's get method is unable to handle an IDCriterion.");
				throw new RuntimeException(e);
			}
			
			if(!c.moveToFirst())
				throw new DataNotFoundException();
			
			Category cat = new Category(dataAdapter);
			cat.setID(dataAdapter.load(c, cat));		
			cat.setNew(false);
			cat.setDirty(false);
			
			return cat;
		}
		finally{
			if(c!=null)
			c.close();
		}
	}
	
	public static List<Category> getAll(Context context, User user){
		return getAll(new CategoryDataAdapter(context), user);
	}
	
	public static List<Category> getAll(DataAdapter<Category> dataAdapter, User user){
		Cursor c = getCursor(dataAdapter, user);
		List<Category> list = new ArrayList<Category>();
		
		while(c.moveToNext()){
			Category cat = new Category(dataAdapter);
			cat.setID(dataAdapter.load(c, cat));
			cat.setNew(false);
			cat.setDirty(false);
			
			list.add(cat);
		}
		
		return list;
	}
	
	public static Cursor getCursor(Context context, User user) {
		return getCursor(new CategoryDataAdapter(context), user);
	}
	
	public static Cursor getCursor(DataAdapter<Category> dataAdapter, User user){		
		try {
			return dataAdapter.get(new UserCriterion(user));
		} catch (UnhandledCriteriaException e) {
			Log.e(TAG, "The Data Adapter's get method is unable to handle an IDCriterion.");
			throw new RuntimeException(e);
		}
	}

	public void setName(String name) {
		if(name==null || name.trim().length() == 0)
			throw new IllegalArgumentException("name cannot be null, empty, or composed entirely of whitespace");
		this.name = name;
		setDirty(true);
	}

	public String getName() {
		return this.name;
	}
	
	public void setUser(User user){
		if(user==null)
			throw new IllegalArgumentException("user cannot be null");
		this.user = user;
		setDirty(true);
	}
	
	public User getUser(){
		return user;
	}
	
	public String toString() {
		return name;
	}
}
